home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / BSSTACK.C < prev    next >
C/C++ Source or Header  |  1995-08-04  |  6KB  |  207 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    bsstack.c
  5. //   Title:    Base library
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //
  24. //    This module contains a debug stack monitor.
  25. //    It contains routines to monitor stack space usage under DOS and 
  26. //    Borland C++ only.
  27. //
  28. //    The code in this module should be written entirely in C. 
  29. //    Do not use any C++ constructs.
  30. //
  31. //    This module is portable to:
  32. //        DOS 3.X+
  33. //        MS Windows 3.X+
  34. //        OS/2 2.X+
  35. //        OS/2 2.0 PM
  36. //        SCO UNIX.
  37. //
  38. //    The following compilers are supported:
  39. //        MSC 6.0A
  40. //        MSC/C++ 7.0
  41. //        Borland C++ 3.1 for DOS
  42. //        Borland C++ 1.0 for OS/2 2.X
  43. //        SCO UNIX cc
  44. //
  45. //----------------------------------------------------------------------------
  46. #include <bs.h>
  47.  
  48.  
  49. //----------------------------------------------------------------------------
  50. //    Stack probe
  51. //----------------------------------------------------------------------------
  52. #if COMPILER_BORLAND
  53. extern unsigned _stklen;
  54. #endif
  55.  
  56. #define SIZE_OF_EMULATOR     (415)       // Account for floating
  57. #define STACK_FILL_CHAR     (0x5A)      // Character used to mark the stack
  58.  
  59. #if OS_WINDOWS                                    // Windows local heap information
  60. typedef struct
  61. {
  62.     BYTE bReserved[6];
  63.     BYTE _NEAR_ *npbLocalHeap;
  64.     BYTE _NEAR_ *npbAtomTable;
  65.     BYTE _NEAR_ *npbStackTop;
  66.     BYTE _NEAR_ *npbStackMin;
  67.     BYTE _NEAR_ *npbStackBtm;
  68. } LOCALHEAPINFO;
  69. BASETYPE(LOCALHEAPINFO);
  70. #endif
  71.  
  72. //----------------------------------------------------------------------------
  73. //   Description:    Check stack high-water mark. Scan the stack until a changed
  74. //                          word is found.
  75. //                          This routine only functions under DOS and Borland C++ v3.1 
  76. //                        using the large memory model.
  77. //                        It assumes that the stack is located in a separate segment.
  78. //    Parameters:
  79. //       Returns:    TRUE if successful.
  80. //----------------------------------------------------------------------------
  81. VOID FN_E CheckStack(void)
  82. {
  83. #if COMPILE_DEBUG
  84.     FILE *file;
  85.     unsigned count= 0;                // Amount of unused stack space
  86.    unsigned max = 0;
  87.  
  88. #if COMPILER_BORLAND && OS_DOS
  89.  
  90.     char far *sp;                     // Far memory model pointer
  91.                                                 // Initialize the pointer
  92.     sp = MK_FP(_SS, SIZE_OF_EMULATOR+1);
  93.     if(_SP >  SIZE_OF_EMULATOR)      // Check for stack overflow
  94.         {
  95.         while(sp < MK_FP(_SS,_SP))    // Check for stack overflow
  96.             {
  97.             if(*sp != (char)STACK_FILL_CHAR)    // Compare pointer value to
  98.                 break;                              // fill character
  99.             count++;                         // Count unused stack space
  100.             sp++;                            // Increment pointer
  101.             }
  102.         }
  103.     Assert(count <= _stklen);
  104.     count = (SIZET)(_stklen - count);
  105.     max = _stklen;
  106.  
  107. #elif OS_WINDOWS
  108.     PLOCALHEAPINFO plhi;
  109. #    if !COMPILER_BORLAND
  110.         unsigned _SS;
  111.         _asm { 
  112.             mov ax, ss
  113.             mov [_SS], ax 
  114.             mov ax, 01h
  115.         }
  116. #    endif  
  117.                                                                                                                     
  118.     plhi = MAKEP(_SS, 0);
  119.     if (plhi->npbStackTop)
  120.         {
  121.         PBYTE pbStackTop = MAKEP(_SS, plhi->npbStackTop);
  122.         PBYTE pbStackBtm = MAKEP(_SS, plhi->npbStackBtm);
  123.  
  124.         pbStackTop++;
  125.         max = (SIZET)(pbStackBtm - pbStackTop);
  126.        while (*pbStackTop == STACK_FILL_CHAR)
  127.            pbStackTop++;
  128.  
  129.         count = (SIZET)(pbStackBtm - pbStackTop);
  130.         }
  131.  
  132. #endif 
  133.  
  134.     if (!LogEnabled())
  135.         return ;
  136.     if (max && (file = fopen("stack.log", "a+t")) != NULL)
  137.         {
  138.         fprintf(file, "%u of %u stack bytes used (%ld %%).\n",
  139.             count, (SIZET)max, ((LONG)count * 100L) / (LONG)max);
  140.         fclose(file);
  141.         }
  142. #endif
  143.     return ;
  144. }
  145.  
  146.  
  147. //----------------------------------------------------------------------------
  148. //   Description:    This routine clear the stack to a predetermined value.
  149. //                          These values will be checked at termination to determine
  150. //                        a high water mark on the stack.
  151. //                          This routine only functions under DOS and Borland C++ v3.1
  152. //                        using the large memory model and under Windows
  153. //                        Under DOS, it assumes that the stack is located in a 
  154. //                        separate segment.
  155. //    Parameters:
  156. //       Returns:
  157. //----------------------------------------------------------------------------
  158. VOID FN_E ClearStack(void)
  159. {
  160. #if COMPILE_DEBUG
  161. #if COMPILER_BORLAND && OS_DOS
  162.  
  163.     char far *sp;                          // Far memory model stack pointer
  164.     sp = MK_FP(_SS, _SP - 1);               // Initialize sp to point to
  165.                                                     // the next available space on
  166.                                                     // the stack.
  167.     LogEnabled();                                // Call to be sure globals initialized
  168.     while(sp > (char far *)SIZE_OF_EMULATOR)
  169.         {
  170.         *sp = STACK_FILL_CHAR;             // Initialize unused stack space
  171.         sp--;
  172.         }
  173.     BaseExitFunc((PFNEXIT)CheckStack, SYS_EXIT_PRIORITY+1);
  174.     
  175. #elif OS_WINDOWS
  176.  
  177.     PLOCALHEAPINFO plhi;
  178. #    if !COMPILER_BORLAND
  179.         unsigned _SP, _SS;
  180.         _asm { 
  181.             mov ax, sp
  182.             mov [_SP], ax
  183.             mov ax, ss
  184.             mov [_SS], ax
  185.         }
  186. #    endif                                                                                                                      
  187.     plhi = MAKEP(_SS, 0);
  188.     LogEnabled();                                /* Call to be sure globals initialized */
  189.     if (plhi->npbStackTop)
  190.         {
  191.         PBYTE pbStackTop = MAKEP(_SS, plhi->npbStackTop);
  192.         PBYTE pbStackNow = MAKEP(_SS, _SP);
  193.  
  194.         pbStackNow -= 2;
  195.         while (pbStackTop < pbStackNow)
  196.             *pbStackNow-- = STACK_FILL_CHAR;
  197.         }
  198.     BaseExitFunc((PFNEXIT)CheckStack, SYS_EXIT_PRIORITY+1);
  199.  
  200. #endif
  201. #endif
  202.     return;
  203. }
  204. //----------------------------------------------------------------------------
  205. //------------------------------- End of File --------------------------------
  206. //----------------------------------------------------------------------------
  207.